package com.ermace.robo.jumper.game.Player.AI;

import java.util.List;
import java.util.Random;

import com.ermace.robo.jumper.game.GameView;
import com.ermace.robo.jumper.game.Player.Position;
import com.ermace.robo.jumper.game.Player.Robot;

public abstract class AI {
	
	protected static final Position LEFT = new Position(0,0);
	protected static final Position RIGHT = new Position(GameView.SCREEN_WIDTH,0);
	
	protected Robot robot;
	protected List<Robot> opponents;
	protected Robot target = null;
	protected Random rand = AIThread.getRandom();
	
	protected long currentTime;
	protected double actionTime = 0;

	protected long previousTime = System.currentTimeMillis();
	
	public AI(Robot robot, List<Robot> opponents)
	{
		this.robot = robot;
		this.opponents = opponents;
	}
	
	protected Robot getTarget() {
		return target;
	}
	
	public final void nextMove() {
		currentTime = System.currentTimeMillis();

		if (target == null)
			if(! switchTarget())
				return;	// Couldn't find a target
		
		if (! target.isAlive())
			target = null;
		
		if (target == null) {
			robot.stop();
			actionTime = 0;
			return; // Geen target dus kan niet berekenen.
		} else {
			actionTime -= (currentTime - previousTime) / 1000.0;
			calculateNextMove();
		}

		previousTime = currentTime;
	}
	
	protected final boolean switchTarget() {
		Robot closest = getClosestRobot();
		
		if (closest == null)
			return false;	// kon geen target vinden
		
		target = closest;
		return true;
	}

	/**
	 * 
	 * @return 	The robot closest to the AI that is alive.
	 * 			Null if there are no robots alive excluding the AI.
	 */
	protected Robot getClosestRobot() {
		double minDistance = 2 * GameView.SCREEN_WIDTH;
		double distance;
		Robot result = null;
		for (Robot opponent: opponents) {
			if (opponent != robot && opponent.isAlive()) {
				distance = robot.getPosition().getDistanceTo(opponent.getPosition());
				minDistance = Math.min(minDistance, distance);
				if (minDistance == distance)
					result = opponent;
			}
		}
		
		return result;
	}
	
	protected abstract void calculateNextMove();
}
